//! pGina winLDAP plugin
/*!

Some code has been taken from ldapAuth_plus (http://www.pgina.org/index.php/Plugins:LDAP_Auth). 
Please observe their licenses as well if you use develop based upon this code. 


LTIA - Applied Information Technology Lab
UNESP - Univ Estadual Paulista, Bauru

*/

#include "stdafx.h"
#include "winLDAP.h"
#include "ConfigUser.h"
#include ".\configuser.h"
#include <vector>

using namespace std;



// CConfigUser dialog

IMPLEMENT_DYNAMIC(CConfigUser, CDialog)
CConfigUser::CConfigUser(CWnd* pParent /*=NULL*/)
	: CDialog(CConfigUser::IDD, pParent)
	, m_NewAccount(_T(""))
{
	hasLoaded = false;
}

CConfigUser::~CConfigUser()
{
}

void CConfigUser::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_ADMINLIST, m_AccountList);
	DDX_Text(pDX, IDC_NEWADMIN, m_NewAccount);
//	DDX_Control(pDX, IDC_COMBO1, ccomboboxChoiceGroups);
	DDX_Control(pDX, IDC_WindowsGroups, listWindowdGroups);

	DWORD numOfLocalGroups= 0;
	DWORD totalentries = 0;
	LPBYTE parameter = new BYTE();
	LOCALGROUP_USERS_INFO_0 *group = new LOCALGROUP_USERS_INFO_0();
	NetLocalGroupEnum(NULL, 0, &parameter, MAX_PREFERRED_LENGTH  , &numOfLocalGroups, &totalentries, NULL);

	if(!hasLoaded)
	{
		loadListsFromReg();
		hasLoaded = true;

		for(int i=0; i < totalentries; i++)
	{
		group = (LOCALGROUP_USERS_INFO_0 *) parameter;
		listWindowdGroups.AddString(group->lgrui0_name);
		parameter+= sizeof(LOCALGROUP_USERS_INFO_0);
	}

	}
	

	
	//\	for (int i = 0; i <listWindowdGroups.GetCount(); i++)
	//{
	//	listWindowdGroups.DeleteString(i);
	//}


	
	//adiciona opcao No Login
	listWindowdGroups.AddString(L"No Login");

}


BEGIN_MESSAGE_MAP(CConfigUser, CDialog)
	ON_BN_CLICKED(IDC_ADDADMIN, OnAdd)
	ON_BN_CLICKED(IDC_DELETEADMIN, OnRemove)
	ON_EN_CHANGE(IDC_NEWADMIN, &CConfigUser::OnEnChangeNewadmin)
	ON_LBN_SELCHANGE(IDC_ADMINLIST, &CConfigUser::OnLbnSelchangeAdminlist)
END_MESSAGE_MAP()


// CConfigUser message handlers
void CConfigUser::OnOK()
{
	return;
}

void CConfigUser::OnAdd()
{
	// TODO: Add your control notification handler code here
 	UpdateData(TRUE);

	vector<CString> labelList;

	if (m_NewAccount == "") {
		MessageBox(L"Please enter a valid username", L"LDAPAuth", MB_OK);
		UpdateData(FALSE);
		return;
	}

	int index = listWindowdGroups.GetSelCount();

 	if (!index)
	{
		MessageBox(L"Please select one group", L"LDAPAuth", MB_OK);
		UpdateData(FALSE);
		return;
	}
	else
	{
		
		CString nameRegGroup = L"";
		CString label = L"";

		// Popula o vector labelList como sgrupos selecionado
		for (int i = 0; i< listWindowdGroups.GetCount() ; i++)
		{
			if (listWindowdGroups.GetSel(i))
			{
				listWindowdGroups.GetText(i, label);
				labelList.push_back(label);
			}
		}


		for (int i = 0; i < labelList.size() ; i++ )
		{
			char psid_buffer[1024];
			PSID psid = (PSID) psid_buffer;
			DWORD sid_length = 1024;
			DWORD gid;
			SID_NAME_USE acc_type;
			WCHAR domain_name[100];
			DWORD domname_len = 100;

			if (LookupAccountName(NULL, labelList[i], psid, &sid_length, domain_name, &domname_len, &acc_type)) 
				if (IsValidSid(psid))
					gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);

			nameRegGroup.Append(L":");

			if(gid==DOMAIN_ALIAS_RID_ADMINS)
				nameRegGroup.Append(L"w_def_ADMIN");
			else if(gid==DOMAIN_ALIAS_RID_USERS)
					nameRegGroup.Append(L"w_def_USER");
			else if(gid==DOMAIN_ALIAS_RID_GUESTS)
					nameRegGroup.Append(L"w_def_GUEST");
			else if(gid==DOMAIN_ALIAS_RID_POWER_USERS)
					nameRegGroup.Append(L"w_def_POWERUSER");
			else if(gid==DOMAIN_ALIAS_RID_BACKUP_OPS)
					nameRegGroup.Append(L"w_def_BACKUPOP");
			else if(gid==DOMAIN_ALIAS_RID_REPLICATOR)
					nameRegGroup.Append(L"w_def_REPLICATOR");
			else if(gid==DOMAIN_ALIAS_RID_ACCOUNT_OPS)
					nameRegGroup.Append(L"w_def_ACCTOP");
			else if(gid==DOMAIN_ALIAS_RID_SYSTEM_OPS)
					nameRegGroup.Append(L"w_def_SYSOP");
			else if(gid==DOMAIN_ALIAS_RID_PRINT_OPS)
					nameRegGroup.Append(L"w_def_PRINTOP");
			// adicionada opcao pra nao fazer login
			else if(label.Compare(L"No Login") == 0)
				nameRegGroup.Append(L"w_def_NOLOGIN");
			else
				 nameRegGroup.Append(labelList[i]);
		}

		m_NewAccount.Append(nameRegGroup);
		m_AccountList.AddString(m_NewAccount);

	}

	m_NewAccount = TEXT("");
	UpdateData(FALSE);
}

void CConfigUser::OnRemove()
{
	// TODO: Add your control notification handler code here
	if(m_AccountList.GetCurSel() >= 0)
		m_AccountList.DeleteString(m_AccountList.GetCurSel());
}


void CConfigUser::loadListsFromReg(void)
{
	// Load the content for the lists from the registry 
	WCHAR currentName[256];
	int x=0;
	CString contextValue = NULL;

	swprintf(currentName,TEXT("%d"), x);
	contextValue = regReadString(currentName);
	while(contextValue.GetLength() > 0)
	{
		m_AccountList.AddString(contextValue);
		x++;
        swprintf(currentName,TEXT("%d"),x);
		contextValue = regReadString(currentName);
	}
}

void CConfigUser::saveListsToReg(void)
{
	WCHAR currentName[256];
	CString value = NULL;
	int x = 0;

	for(x = 0; x < m_AccountList.GetCount(); x++)
	{
		m_AccountList.GetText(x,value);
		swprintf(currentName,TEXT("%d"),x);
		regWriteString(value.GetBuffer(value.GetLength()),currentName);
	}

	// Now loop through and delete any existing contexts above our last saved one
	x = m_AccountList.GetCount();
	swprintf(currentName,TEXT("%d"),x);
	value = regReadString(currentName);

	while(value.GetLength() > 0)
	{
		regDelValue(currentName);
		x++;
		swprintf(currentName,TEXT("%d"),x);
		value = regReadString(currentName);
	}
}

void CConfigUser::OnSave(void)
{
	UpdateData(TRUE);
	WCHAR currentName[256];
	CString value = NULL;
	int x = 0;

	for(x = 0; x < m_AccountList.GetCount(); x++)
	{
		m_AccountList.GetText(x,value);
		swprintf(currentName,TEXT("%d"),x);
		regWriteString(value.GetBuffer(value.GetLength()),currentName);
	}

	// Now loop through and delete any existing contexts above our last saved one
	x = m_AccountList.GetCount();
	swprintf(currentName,TEXT("%d"),x);
	value = regReadString(currentName);

	while(value.GetLength() > 0)
	{
		regDelValue(currentName);
		x++;
		swprintf(currentName,TEXT("%d"),x);
		value = regReadString(currentName);
	}
}

TCHAR * CConfigUser::regReadString(LPCTSTR location)
{
    LONG lResult;
	HKEY hKey;
    DWORD dwBytesRead = 2048;
    TCHAR result[2048];
    TCHAR *ret;
	
	lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\pGina\\ldapauth\\GroupMap"),0,KEY_QUERY_VALUE,&hKey);

    if(lResult == ERROR_SUCCESS)
    {
    	lResult = RegQueryValueEx(hKey,location,NULL,NULL,(LPBYTE)&result,&dwBytesRead);

        if(lResult == ERROR_SUCCESS)
        {
            if(dwBytesRead > 0)
            {
				if(!_tcscmp(result,L"")) // If its just a space
				{
//				    return NULL;                                                                                 
				}
				else
				{
//                  _tcsdup allocates memory, so we don't need to
//					ret = (TCHAR *)malloc((sizeof(TCHAR) * dwBytesRead) + 1);
					ret = _tcsdup(result);
					RegCloseKey(hKey);
					return ret;
				}
            }
            else
            {
//                return NULL;
            }
        }
    }
    RegCloseKey(hKey);
    return NULL;
}

BOOL CConfigUser::regWriteString(LPTSTR value,LPCTSTR location)
{
    HKEY hKey;

    if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\pGina\\ldapauth\\GroupMap"),0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,NULL) == ERROR_SUCCESS)
    {
        if(value != NULL)
            if(RegSetValueEx(hKey,location,0,REG_SZ,(CONST BYTE *) value, (DWORD)(_tcslen(value)*sizeof(TCHAR))) == ERROR_SUCCESS)
            {
                RegFlushKey(hKey);
                RegCloseKey(hKey);
                return true;
            }
    }

    RegFlushKey(hKey);
    RegCloseKey(hKey);
    return false;
}

void CConfigUser::regDelValue(LPCTSTR location)
{
	HKEY    hKey;
	LONG    lResult;
	
	lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
							_T("SOFTWARE\\pGina\\ldapauth\\GroupMap"),
							0, KEY_WRITE, &hKey);

	if(lResult == ERROR_SUCCESS)
	{
		lResult = RegDeleteValue(hKey,location);
		RegFlushKey(hKey);
	}

	RegCloseKey(hKey);
}


void CConfigUser::OnEnChangeNewadmin()
{
	// TODO:  If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.

	// TODO:  Add your control notification handler code here
}

void CConfigUser::OnLbnSelchangeAdminlist()
{
	// TODO: Add your control notification handler code here
}
